package SQL_L

import org.apache.spark.sql.SparkSession
import org.junit.Test

class unTypedTransformation {
  //创建SparkSession
  val spark = SparkSession.builder()
    .master("local[6]")
    .appName("transformation")
    .getOrCreate()
  //隐式转换
  import spark.implicits._

  /**
   * 选择
   */
  @Test
  def select() = {
    val ds = Seq(Person("zhangsan", 12), Person("zhangsan", 8), Person("lisi", 15)).toDS()
    //下面两个结果一致
    ds.select($"name").show()
    ds.select('name).show()
  }

  /**
   * 在 SQL 语句中, 经常可以在 select 子句中使用 count(age), rand() 等函数,
   * 在 selectExpr 中就可以使用这样的 SQL 表达式, 同时使用 select 配合 expr 函数也可以做到类似的效果
   */
  @Test
  def selectExpr() = {
    val ds = Seq(Person("zhangsan", 12), Person("zhangsan", 8), Person("lisi", 15)).toDS()
    ds.selectExpr("sum(age)").show()
    ds.selectExpr("*").show()

    //使用select来达到selectExpr的效果
    import org.apache.spark.sql.functions._
    ds.select(expr("sum(age)")).show()
  }

  /**
   * 新建列
   */
  @Test
  def withColumn() = {
    val ds = Seq(Person("zhangsan", 12), Person("zhangsan", 8), Person("lisi", 15)).toDS()
    import org.apache.spark.sql.functions._
    ds.withColumn("random",expr("rand()"))

    //复制一个新的列
    ds.withColumn("name_new",'name).show()

    //判断某一列
    ds.withColumn("ageOver10",'age >10).show()
  }

  /**
   * 列的重命名
   */
  @Test
  def withColumnRename() = {
    val ds = Seq(Person("zhangsan", 12), Person("zhangsan", 8), Person("lisi", 5)).toDS()
    ds.show()
    ds.withColumnRenamed("age","id").show()
  }

  /**
   * 剪除
   */
  @Test
  def drop() = {
    val ds = Seq(Person("zhangsan", 12), Person("zhangsan", 8), Person("lisi", 15)).toDS()
    ds.drop('age).show()
  }

  @Test
  def gourpBy() = {
    val ds = Seq(Person("zhangsan", 12), Person("zhangsan", 18), Person("lisi", 15)).toDS()

    /**
     *  为什么groupByKey是有类型的？是因为他生成的对象是有类型的
     *  为什么groupBy是无类型的？   是因为他作于于列，生成的的对象是无类型的
     *  建议：尽可能多的使用groupBy
     */
    import org.apache.spark.sql.functions._
    ds.groupBy('name).agg(mean("age")).show()

  }
}
